<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Document</title>
</head>
<body>
	<script>
		// 下面，我们来新建一个简单的构造器函数，并用他再创建两个对象
		function Dog() {
			this.tail = true;
		}
		var benji = new Dog();
		var rusty = new Dog();

		// 和原来一样，即便在benji和resty对象创建之后，我们也依然可以为Dog()的原型添加属性，并且在属性被添加之前就已经存在的对象也可以随时访问这些新属性。现在我们放进去一个新的say()
		Dog.prototype.say = function() {
			return 'Woof!';
		};

		// 这样一来，上面的两个对象都可以访问这两个新方法了
		console.log(benji.say());
		console.log(rusty.say());

		// 如果我们检查一下这些对象的构造器函数，就会发现一些正常
		console.log(benji.constructor == Dog);
		console.log(rusty.constructor == Dog);

		// 现在我们用新定义的对象完全覆盖掉原有的原型对象
		Dog.prototype = {
			paws: 4,
			hair: true
		};

		// 事实证明，这会使原有对象不能访问原型的新增属性，他们依然通过那个神秘链接与原有的原型对象保持联系
		console.log(typeof benji.paws);
		console.log(benji.say());
		console.log(typeof benji.__proto__.say());
		console.log(typeof benji.__proto__.paws);

		// 而我们之后创建的所有对象使用的都是被更新后的prototype对象
		var lucy = new Dog();
		// console.log(lucy.say());
		console.log(lucy.paws);

		// 并且秘密链接__proto__也指向了新的prototype对象
		console.log(typeof lucy.__proto__.say);
		console.log(typeof lucy.__proto__.paws);

		// 但这时候，新对象的constructor属性就不能再保持正确了，原本应该是Dog()引用却指向了Object()。
		console.log(lucy.constructor);
		console.log(benji.constructor);

		// 当然，我们可以通过重新设置constructor属性来解决上述所有的异常
		function Dog() {};
		Dog.prototype = {};
		console.log(new Dog().constructor === Dog);

		Dog.prototype.constructor = Dog;
		console.log(new Dog().constructor === Dog);
	</script>
</body>
</html>